package com.airena.controller;

import com.airena.entity.po.RoleInfo;
import com.airena.result.Result;
import com.airena.service.IRoleInfoService;
import com.alibaba.dashscope.aigc.multimodalconversation.AudioParameters;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversation;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationParam;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/tts")
@Slf4j
@Tag(name = "TTS接口")
public class TTSController {

    private static final String MODEL = "qwen3-tts-flash";
    
    @Value("${dashscope.api.key}")
    private String apiKey;
    
    @Autowired
    private IRoleInfoService roleInfoService;
    
    // 存储文本到音频URL的映射，用于快速查找已生成的音频
    private static final ConcurrentHashMap<String, String> TEXT_TO_AUDIO_MAP = new ConcurrentHashMap<>();
    
    // 创建ObjectMapper实例用于JSON处理
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @PostMapping("/synthesize")
    @Operation(summary = "文本转语音")
    public Result<String> synthesizeText(@RequestParam String text, 
                                         @RequestParam(required = false, defaultValue = "CHERRY") String voice,
                                         @RequestParam(required = false, defaultValue = "English") String language,
                                         @RequestParam(required = false) Long roleId) {
        
        // 如果提供了角色ID，则从角色信息中获取TTS配置
        if (roleId != null) {
            try {
                RoleInfo roleInfo = roleInfoService.getRoleInfo(roleId);
                if (roleInfo != null && roleInfo.getTtsConfig() != null && !roleInfo.getTtsConfig().isEmpty()) {
                    JsonNode ttsConfig = objectMapper.readTree(roleInfo.getTtsConfig());
                    if (ttsConfig.has("voice")) {
                        voice = ttsConfig.get("voice").asText();
                    }
                }
            } catch (Exception e) {
                log.warn("获取角色TTS配置失败，使用默认音色: {}", e.getMessage());
            }
        }
        
        try {
            // 检查是否已经为该文本生成过音频
            String cachedAudioUrl = TEXT_TO_AUDIO_MAP.get(text);
            if (cachedAudioUrl != null) {
                log.info("使用缓存的音频URL: {}", cachedAudioUrl);
                return Result.success(cachedAudioUrl);
            }
            
            MultiModalConversation conv = new MultiModalConversation();
            MultiModalConversationParam param = MultiModalConversationParam.builder()
                    .model(MODEL)
                    .text(text)
                    .apiKey(apiKey)
                    .voice(AudioParameters.Voice.valueOf(voice))
                    .languageType(language)
                    .build();
            MultiModalConversationResult result = conv.call(param);
            String audioUrl = result.getOutput().getAudio().getUrl();
            
            // 缓存文本到音频URL的映射
            TEXT_TO_AUDIO_MAP.put(text, audioUrl);
            
            log.info("文本转语音成功，生成的音频URL: {}", audioUrl);
            return Result.success(audioUrl);
        } catch (Exception e) {
            log.error("文本转语音失败", e);
            return Result.error("文本转语音失败: " + e.getMessage());
        }
    }

    @GetMapping("/audio/stream")
    @Operation(summary = "获取音频流")
    public void getAudioStream(@RequestParam String text,
                               @RequestParam(required = false, defaultValue = "CHERRY") String voice,
                               @RequestParam(required = false, defaultValue = "English") String language,
                               @RequestParam(required = false) Long roleId,
                               HttpServletResponse response) {
        
        // 如果提供了角色ID，则从角色信息中获取TTS配置
        if (roleId != null) {
            try {
                RoleInfo roleInfo = roleInfoService.getRoleInfo(roleId);
                if (roleInfo != null && roleInfo.getTtsConfig() != null && !roleInfo.getTtsConfig().isEmpty()) {
                    JsonNode ttsConfig = objectMapper.readTree(roleInfo.getTtsConfig());
                    if (ttsConfig.has("voice")) {
                        voice = ttsConfig.get("voice").asText();
                    }
                }
            } catch (Exception e) {
                log.warn("获取角色TTS配置失败，使用默认音色: {}", e.getMessage());
            }
        }
        
        try {
            String audioUrl = null;
            
            // 检查是否已经为该文本生成过音频
            String cachedAudioUrl = TEXT_TO_AUDIO_MAP.get(text);
            if (cachedAudioUrl != null) {
                audioUrl = cachedAudioUrl;
                log.info("使用缓存的音频URL: {}", audioUrl);
            } else {
                // 生成新的音频
                MultiModalConversation conv = new MultiModalConversation();
                MultiModalConversationParam param = MultiModalConversationParam.builder()
                        .model(MODEL)
                        .text(text)
                        .apiKey(apiKey)
                        .voice(AudioParameters.Voice.valueOf(voice))
                        .languageType(language)
                        .build();
                MultiModalConversationResult result = conv.call(param);
                audioUrl = result.getOutput().getAudio().getUrl();
                
                // 缓存文本到音频URL的映射
                TEXT_TO_AUDIO_MAP.put(text, audioUrl);
                log.info("文本转语音成功，生成的音频URL: {}", audioUrl);
            }
            
            // 设置响应头
            response.setContentType("audio/wav");
            response.setHeader("Content-Disposition", "inline; filename=\"audio.wav\"");
            
            // 从DashScope获取音频流并返回给客户端
            URL url = new URL(audioUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");
            
            InputStream in = connection.getInputStream();
            OutputStream out = response.getOutputStream();
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            
            out.flush();
            in.close();
            connection.disconnect();
        } catch (Exception e) {
            log.error("获取音频流失败", e);
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "获取音频流失败: " + e.getMessage());
            } catch (Exception ex) {
                log.error("发送错误响应失败", ex);
            }
        }
    }
    
    @GetMapping("/audio/url")
    @Operation(summary = "获取音频URL")
    public Result<String> getAudioUrl(@RequestParam String text,
                                      @RequestParam(required = false, defaultValue = "CHERRY") String voice,
                                      @RequestParam(required = false, defaultValue = "English") String language,
                                      @RequestParam(required = false) Long roleId) {
        
        // 如果提供了角色ID，则从角色信息中获取TTS配置
        if (roleId != null) {
            try {
                RoleInfo roleInfo = roleInfoService.getRoleInfo(roleId);
                if (roleInfo != null && roleInfo.getTtsConfig() != null && !roleInfo.getTtsConfig().isEmpty()) {
                    JsonNode ttsConfig = objectMapper.readTree(roleInfo.getTtsConfig());
                    if (ttsConfig.has("voice")) {
                        voice = ttsConfig.get("voice").asText();
                    }
                }
            } catch (Exception e) {
                log.warn("获取角色TTS配置失败，使用默认音色: {}", e.getMessage());
            }
        }
        
        try {
            // 检查是否已经为该文本生成过音频
            String cachedAudioUrl = TEXT_TO_AUDIO_MAP.get(text);
            if (cachedAudioUrl != null) {
                log.info("使用缓存的音频URL: {}", cachedAudioUrl);
                return Result.success(cachedAudioUrl);
            }
            
            // 生成新的音频
            MultiModalConversation conv = new MultiModalConversation();
            MultiModalConversationParam param = MultiModalConversationParam.builder()
                    .model(MODEL)
                    .text(text)
                    .apiKey(apiKey)
                    .voice(AudioParameters.Voice.valueOf(voice))
                    .languageType(language)
                    .build();
            MultiModalConversationResult result = conv.call(param);
            String audioUrl = result.getOutput().getAudio().getUrl();
            
            // 缓存文本到音频URL的映射
            TEXT_TO_AUDIO_MAP.put(text, audioUrl);
            
            log.info("文本转语音成功，生成的音频URL: {}", audioUrl);
            return Result.success(audioUrl);
        } catch (Exception e) {
            log.error("获取音频URL失败", e);
            return Result.error("获取音频URL失败: " + e.getMessage());
        }
    }
}